package com.demo2do.fms.entity.vehicle.trailer;

import java.math.BigDecimal;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.format.annotation.DateTimeFormat;

import com.demo2do.fms.entity.authority.Organization;
import com.demo2do.fms.entity.supplier.common.Supplier;
import com.demo2do.fms.entity.vehicle.AssetStatus;
import com.demo2do.fms.entity.vehicle.AuditStatus;
import com.demo2do.fms.entity.vehicle.DeclareStatus;
import com.demo2do.fms.entity.vehicle.VehicleStatus;

/**
 * 挂车
 * 
 * @author Wy
 *
 */
@Entity
@Table(name = "FMS_TRAILER")
@DynamicInsert
@DynamicUpdate
public class Trailer {
    
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator")
    @SequenceGenerator(name = "generator", sequenceName = "HIBERNATE_SEQUENCE", allocationSize = 1)
    private Long id;
    
    /** 所属公司 */
    @ManyToOne(fetch = FetchType.LAZY, optional = true)
    @JoinColumn(name = "organization_id", referencedColumnName = "id")
    private Organization organization;

    /** 所属供方 */
    @ManyToOne(fetch = FetchType.LAZY, optional = true)
    @JoinColumn(name = "supplier_id", referencedColumnName = "id")
    private Supplier supplier;
    
    /** 产证所有者 */
    private String floorLord;
    
    /** 中文车牌号 */
    @Column(name = "BRAND_CN_CODE")
    private String brandCNCode;
    
    /** VIN码 */
    @Column(name = "VIN")
    private String vincode;
    
    /** 品牌 */
    private String brand;
    
    /** 长 */
    private BigDecimal length;
    
    /** 宽 */
    private BigDecimal width;
    
    /** 高 */
    private BigDecimal height;
    
    /** 挂车类型 */
    @Enumerated(EnumType.STRING)
    private TrailerType trailerType;
    
    /** 车辆类型（行驶证） */
    @Enumerated(EnumType.STRING)
    private TrailerVehicleType vehicleType;
    
    /** 装载量*/
    private BigDecimal trainload;
    
    /** 轴数 */
    private BigDecimal axles;

    /** 年审时间(挂车年检有效期至) 年月 */
    @DateTimeFormat(pattern = "yyyy-MM")
    private Date annualInspectionDate;
    
    /** 资产状态， 只存在VAM车辆中 */
    @Enumerated(EnumType.STRING)
    private AssetStatus assetStatus;
    
    /** 行驶证 */
    private String drivingLicense;

    /** 行驶副本扫描件 */
    private String drivingLicenseCopy;

    /** 45度角照片 */
    private String vehiclePhoto;

    /** 审核状态 */
    @Enumerated(EnumType.STRING)
    private AuditStatus status;
    
    /** 引入申报时间 */
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date declareTime;
    
    /** 引入申报状态 */
    @Enumerated(EnumType.STRING)
    private DeclareStatus declareStatus;
    
    /** 驳回理由 */
    private String rejectReason;
    
    /** 车辆状态 */
    @Enumerated(EnumType.STRING)
    private VehicleStatus vehicleStatus;
    
    /** 是否同步TMS */
    @Column(name = "is_synchronize")
    private boolean synchronize;
    
    /** 是否绑定牵引车 */
    @Column(name = "is_bind")
    private boolean bind;
    
    /** 是否来自VAM */
    @Column(name = "is_vam")
    private boolean vam;
    
    /** vam车辆id */
    private Long vamId;
    
    /** 创建者 */
    @Column(name = "CREATOR")
    private Long creator;

    /** 创建时间 */
    @Column(name = "CREATE_TIME")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;

    /** 最近修改者 */
    @Column(name = "LAST_OPERATOR")
    private Long lastOperator;

    /** 最近修改时间 */
    @Column(name = " LAST_MODIFY_TIME")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date lastModifyTime;

    @Column(name = "IS_DISABLED")
    private Boolean disabled;

    /**
     * The default constructor
     */
    public Trailer() {
    }
    
    /**
     * FMS添加车辆
     * 
     * @param floorLord
     * @param trailerType
     * @param brandCNCode
     * @param vincode
     * @param length
     * @param width
     * @param height
     * @param trainload
     * @param annualInspectionDate
     * @param axles
     * @param organization
     * @param supplier
     * @param operator
     */
    public Trailer(String floorLord, TrailerType trailerType, String brandCNCode, String vincode, BigDecimal length,
            BigDecimal width, BigDecimal height, BigDecimal trainload, Date annualInspectionDate, BigDecimal axles, TrailerVehicleType vehicleType, String brand,
            Organization organization, Supplier supplier, Long operator) {
        
        this.floorLord = floorLord;
        this.trailerType = trailerType;
        this.brandCNCode = brandCNCode;
        this.vincode = vincode;
        this.length = length;
        this.width = width;
        this.height = height;
        this.trainload = trainload;
        this.annualInspectionDate = annualInspectionDate;
        this.axles = axles;
        this.vehicleType = vehicleType;
        this.brand = brand;
        
        this.status = AuditStatus.EDITING;
        this.declareStatus = DeclareStatus.UNSYNC;
        this.vehicleStatus = VehicleStatus.NORMAL;
        
        this.organization = organization;
        this.supplier = supplier;

        this.bind = false;
        this.vam = false;
        this.synchronize = false;
        
        this.creator = operator;
        this.createTime = new Date();
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        this.disabled = false;
        
    }
    
    /**
     * VAM添加车辆
     * 
     * @param floorLord
     * @param trailerType
     * @param brandCNCode
     * @param vincode
     * @param length
     * @param width
     * @param height
     * @param trainload
     * @param annualInspectionDate
     * @param axles
     * @param vehicleType
     * @param organization
     * @param supplier
     * @param assetStatus
     * @param vamId
     * @param operator
     */
    public Trailer(String floorLord, TrailerType trailerType, String brandCNCode, String brand, String vincode, BigDecimal length,
            BigDecimal width, BigDecimal height, BigDecimal trainload, Date annualInspectionDate, BigDecimal axles, TrailerVehicleType vehicleType,
            String drivingLicense, String drivingLicenseCopy, String vehiclePhoto,
            Organization organization, Supplier supplier, AssetStatus assetStatus, Long vamId, Long operator) {
        
        this.floorLord = floorLord;
        this.trailerType = trailerType;
        this.brandCNCode = brandCNCode;
        this.brand = brand;
        this.vincode = vincode;
        this.length = length;
        this.width = width;
        this.height = height;
        this.trainload = trainload;
        this.annualInspectionDate = annualInspectionDate;
        this.axles = axles;
        this.vehicleType = vehicleType;
        this.drivingLicense = drivingLicense;
        this.drivingLicenseCopy = drivingLicenseCopy;
        this.vehiclePhoto = vehiclePhoto;
        
        this.status = AuditStatus.AUDITING;
        this.vehicleStatus = VehicleStatus.NORMAL;
        this.declareStatus = DeclareStatus.UNSYNC;
        this.declareTime = new Date();
        this.rejectReason = null;
        
        this.organization = organization;
        this.supplier = supplier;
        this.assetStatus = assetStatus;
        this.vamId = vamId;

        this.bind = false;
        this.vam = true;
        this.synchronize = false;
        
        this.creator = operator;
        this.createTime = new Date();
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        this.disabled = false;
    }
    
    /**
     * @param organization
     * @param supplier
     * @param createTime
     * @param creator
     * @return
     */
    public Trailer initialize(Organization organization, Supplier supplier, Date createTime, Long creator) {
        
        this.status = AuditStatus.EDITING;
        this.declareStatus = DeclareStatus.UNSYNC;
        this.vehicleStatus = VehicleStatus.NORMAL;
        
        this.organization = organization;
        this.supplier = supplier;

        this.bind = false;
        this.vam = false;
        this.synchronize = false;
        
        this.creator = creator;
        this.createTime = createTime;
        this.lastOperator = creator;
        this.lastModifyTime = createTime;
        this.disabled = false;
        return this;
        
    }
    
    /**
     * VAM更新车辆
     * 
     * @param trailer
     * @return
     */
    public Trailer edit(Trailer trailer) {
        this.floorLord = trailer.floorLord;
        this.trailerType = trailer.trailerType;
        this.brandCNCode = trailer.brandCNCode;
        this.length = trailer.length;
        this.width = trailer.width;
        this.height = trailer.height;
        this.vincode = trailer.vincode;
        this.trainload = trailer.trainload;
        this.annualInspectionDate = trailer.annualInspectionDate;
        this.axles = trailer.axles;
        this.drivingLicense = trailer.getDrivingLicense();
        this.drivingLicenseCopy = trailer.getDrivingLicenseCopy();
        this.vehiclePhoto = trailer.getVehiclePhoto();
        this.assetStatus = trailer.getAssetStatus();
        return this;
    }
    
    /**
     * VAM更新合格车辆
     * 
     * @param trailer
     * @return
     */
    public Trailer editQualifiedField(Trailer trailer) {
        this.brandCNCode = trailer.brandCNCode;
        this.length = trailer.length;
        this.width = trailer.width;
        this.height = trailer.height;
        this.annualInspectionDate = trailer.annualInspectionDate;
        this.axles = trailer.axles;
        this.assetStatus = trailer.getAssetStatus();
        return this;
    }
    
    /**
     * @return
     */
    public Trailer sign() {
        this.synchronize = true;
        return this;
    }
    
    /**
     * @param synchronize
     * @return
     */
    public Trailer sign(boolean synchronize) {
        this.synchronize = synchronize;
        return this;
    }
    
    /**
     * @return
     */
    public String auditMessage() {
        
        if (StringUtils.isBlank(floorLord)) {
            return "产证所有者未录入";
        } else if (trailerType == null) {
            return "挂车类型未录入";
        } else if (StringUtils.isBlank(brandCNCode)) {
            return "中文牌号未录入";
        } else if (StringUtils.isBlank(vincode)) {
            return "VIN码未录入";
        } else if (StringUtils.isBlank(brand)) {
            return "品牌未录入";
        } else if (length == null || width == null || height == null) {
            return "实际长宽高信息未录入";
        } else if (trainload == null) {
            return "满载量未录入";
        } else if (axles == null) {
            return "轴数未录入";
        } else if (annualInspectionDate == null) {
            return "年检有效期至未录入";
        } else if (vehicleType == null) {
            return "车辆类型（行驶证）未录入";
        } else if (StringUtils.isBlank(drivingLicense)) {
            return "行驶证原件扫描件未录入";
        } else if (StringUtils.isBlank(drivingLicenseCopy)) {
            return "行驶副本扫描件未录入";
        } else if (StringUtils.isBlank(vehiclePhoto)) {
            return "45度角照片未录入";
        } else {
            return null;
        }
        
    }
    
    /**
     * @param operator
     * @return
     */
    public Trailer audit(Long operator) {
        
        if (declareStatus.isModified()) {
            this.status = AuditStatus.MODIFIED;
        } else {
            this.status = AuditStatus.AUDITING;
        }
        
        this.declareTime = new Date();
        this.rejectReason = null;
        
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        return this;
    }
    
    /**
     * 引入申报  - 审核通过
     * 
     * @param operator
     * @return
     */
    public Trailer adoptAuditing(Long operator) {
        this.status = AuditStatus.QUALIFIED;
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        return this;
    }
    
    /**
     * 引入申报 - 审核驳回
     * 
     * @param operator
     * @return
     */
    public Trailer rejectAuditing(Long operator) {
        this.status = AuditStatus.REJECTED;
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        return this;
    }
    
    /**
     * @param operator
     * @return
     */
    public Trailer change(Long operator) {
        this.status = AuditStatus.MODIFIED;
        this.declareStatus = DeclareStatus.MODIFIED;
        this.declareTime = new Date();
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        return this;
    }
    
    /**
     * 变更审核 - 通过
     * 
     * @param version
     * @param operator
     * @return
     */
    public Trailer adoptModified(TrailerModifiedVersion version, Long operator) {
        
        this.floorLord = version.getFloorLord();
        this.trailerType = version.getTrailerType();
        this.vincode = version.getVincode();
        this.trainload = version.getTrainload();
        this.annualInspectionDate = version.getAnnualInspectionDate();
        this.axles = version.getAxles();
        this.vehicleType = version.getVehicleType();
        this.brand = version.getBrand();
        
        if (StringUtils.isNotBlank(version.getDrivingLicense())) {
            this.drivingLicense = version.getDrivingLicense();
        }
        if (StringUtils.isNotBlank(version.getDrivingLicenseCopy())) {
            this.drivingLicenseCopy = version.getDrivingLicenseCopy();
        }
        if (StringUtils.isNotBlank(version.getVehiclePhoto())) {
            this.vehiclePhoto = version.getVehiclePhoto();
        }
        
        this.status = AuditStatus.QUALIFIED;
        this.rejectReason = null;
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        return this;
        
    }
    
    /**
     * 转籍
     * 
     * @param supplier
     * @param operator
     * @return
     */
    public Trailer transfer(Supplier supplier, Organization organization, Long operator) {
        this.supplier = supplier;
        this.organization = organization;
        this.bind = false;
        this.status = AuditStatus.EDITING;
        this.declareStatus = DeclareStatus.UNSYNC;
        this.declareTime = null;
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        return this;
    }
    
    /**
     * @param supplier
     * @param organization
     * @param operator
     * @return
     */
    public Trailer transferForVam(Supplier supplier, Organization organization, Long operator) {
        this.supplier = supplier;
        this.organization = organization;
        this.bind = false;
        this.status = AuditStatus.AUDITING;
        this.declareStatus = DeclareStatus.UNSYNC;
        this.declareTime = null;
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        return this;
    }
    
    /**
     * @return
     */
    public Trailer bind() {
        this.bind = true;
        return this;
    }
    
    /**
     * @return
     */
    public Trailer unbind() {
        this.bind = false;
        this.synchronize = false;
        return this;
    }
    
    /**
     * @param operator
     * @return
     */
    public Trailer out(Long operator) {
        this.disabled = true;
        this.bind = false;
        this.vehicleStatus = VehicleStatus.OUT;
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        return this;
    }
    
    /**
     * @param status
     * @return
     */
    public Trailer status(AuditStatus status) {
        this.status = status;
        return this;
    }
    
    /**
     * 
     * @return
     */
    public Trailer disable(Long operator) {
        this.disabled = true;
        this.lastOperator = operator;
        this.lastModifyTime = new Date();
        return this;
    }

    /**
     * @param lastModifyTime
     * @param lastOperator
     * @return
     */
    public Trailer operate(Date lastModifyTime, Long lastOperator) {
        this.lastModifyTime = lastModifyTime;
        this.lastOperator = lastOperator;
        return this;
    }

    /**
    * @description 锁车后车辆改为未审核状态
    * @params []
    * @return com.demo2do.fms.entity.vehicle.trailer.Trailer
    * @author LZJ
    * @date 2020/12/2 16:44
    **/
    public Trailer makeStatusToAuditing() {
        this.status = AuditStatus.AUDITING;
        this.lastModifyTime = new Date();
        return this;
    }

    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }

    /**
     * @return the organization
     */
    public Organization getOrganization() {
        return organization;
    }

    /**
     * @return the supplier
     */
    public Supplier getSupplier() {
        return supplier;
    }

    /**
     * @return the floorLord
     */
    public String getFloorLord() {
        return floorLord;
    }

    /**
     * @return the brandCNCode
     */
    public String getBrandCNCode() {
        return brandCNCode;
    }

    /**
     * @return the vincode
     */
    public String getVincode() {
        return vincode;
    }

    /**
     * @return the brand
     */
    public String getBrand() {
        return brand;
    }

    /**
     * @return the length
     */
    public BigDecimal getLength() {
        return length;
    }

    /**
     * @return the width
     */
    public BigDecimal getWidth() {
        return width;
    }

    /**
     * @return the height
     */
    public BigDecimal getHeight() {
        return height;
    }

    /**
     * @return the trailerType
     */
    public TrailerType getTrailerType() {
        return trailerType;
    }

    /**
     * @return the vehicleType
     */
    public TrailerVehicleType getVehicleType() {
        return vehicleType;
    }

    /**
     * @return the trainload
     */
    public BigDecimal getTrainload() {
        return trainload;
    }

    /**
     * @return the axles
     */
    public BigDecimal getAxles() {
        return axles;
    }

    /**
     * @return the annualInspectionDate
     */
    public Date getAnnualInspectionDate() {
        return annualInspectionDate;
    }

    /**
     * @return the assetStatus
     */
    public AssetStatus getAssetStatus() {
        return assetStatus;
    }

    /**
     * @return the drivingLicense
     */
    public String getDrivingLicense() {
        return drivingLicense;
    }

    /**
     * @return the drivingLicenseCopy
     */
    public String getDrivingLicenseCopy() {
        return drivingLicenseCopy;
    }

    /**
     * @return the vehiclePhoto
     */
    public String getVehiclePhoto() {
        return vehiclePhoto;
    }

    /**
     * @return the status
     */
    public AuditStatus getStatus() {
        return status;
    }

    /**
     * @return the declareTime
     */
    public Date getDeclareTime() {
        return declareTime;
    }

    /**
     * @return the declareStatus
     */
    public DeclareStatus getDeclareStatus() {
        return declareStatus;
    }

    /**
     * @return the rejectReason
     */
    public String getRejectReason() {
        return rejectReason;
    }

    /**
     * @return the vehicleStatus
     */
    public VehicleStatus getVehicleStatus() {
        return vehicleStatus;
    }
    
    /**
     * @return
     */
    public boolean isSynchronize() {
        return synchronize;
    }

    /**
     * @return the bind
     */
    public boolean isBind() {
        return bind;
    }

    /**
     * @return the vam
     */
    public boolean isVam() {
        return vam;
    }

    /**
     * @return the vamId
     */
    public Long getVamId() {
        return vamId;
    }

    /**
     * @return the creator
     */
    public Long getCreator() {
        return creator;
    }

    /**
     * @return the createTime
     */
    public Date getCreateTime() {
        return createTime;
    }

    /**
     * @return the lastOperator
     */
    public Long getLastOperator() {
        return lastOperator;
    }

    /**
     * @return the lastModifyTime
     */
    public Date getLastModifyTime() {
        return lastModifyTime;
    }

    /**
     * @return the disabled
     */
    public Boolean getDisabled() {
        return disabled;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @param organization the organization to set
     */
    public void setOrganization(Organization organization) {
        this.organization = organization;
    }

    /**
     * @param supplier the supplier to set
     */
    public void setSupplier(Supplier supplier) {
        this.supplier = supplier;
    }

    /**
     * @param floorLord the floorLord to set
     */
    public void setFloorLord(String floorLord) {
        this.floorLord = floorLord;
    }

    /**
     * @param brandCNCode the brandCNCode to set
     */
    public void setBrandCNCode(String brandCNCode) {
        this.brandCNCode = brandCNCode;
    }

    /**
     * @param vincode the vincode to set
     */
    public void setVincode(String vincode) {
        this.vincode = vincode;
    }

    /**
     * @param brand the brand to set
     */
    public void setBrand(String brand) {
        this.brand = brand;
    }

    /**
     * @param length the length to set
     */
    public void setLength(BigDecimal length) {
        this.length = length;
    }

    /**
     * @param width the width to set
     */
    public void setWidth(BigDecimal width) {
        this.width = width;
    }

    /**
     * @param height the height to set
     */
    public void setHeight(BigDecimal height) {
        this.height = height;
    }

    /**
     * @param trailerType the trailerType to set
     */
    public void setTrailerType(TrailerType trailerType) {
        this.trailerType = trailerType;
    }

    /**
     * @param vehicleType the vehicleType to set
     */
    public void setVehicleType(TrailerVehicleType vehicleType) {
        this.vehicleType = vehicleType;
    }

    /**
     * @param trainload the trainload to set
     */
    public void setTrainload(BigDecimal trainload) {
        this.trainload = trainload;
    }

    /**
     * @param axles the axles to set
     */
    public void setAxles(BigDecimal axles) {
        this.axles = axles;
    }

    /**
     * @param annualInspectionDate the annualInspectionDate to set
     */
    public void setAnnualInspectionDate(Date annualInspectionDate) {
        this.annualInspectionDate = annualInspectionDate;
    }

    /**
     * @param assetStatus the assetStatus to set
     */
    public void setAssetStatus(AssetStatus assetStatus) {
        this.assetStatus = assetStatus;
    }

    /**
     * @param drivingLicense the drivingLicense to set
     */
    public void setDrivingLicense(String drivingLicense) {
        this.drivingLicense = drivingLicense;
    }

    /**
     * @param drivingLicenseCopy the drivingLicenseCopy to set
     */
    public void setDrivingLicenseCopy(String drivingLicenseCopy) {
        this.drivingLicenseCopy = drivingLicenseCopy;
    }

    /**
     * @param vehiclePhoto the vehiclePhoto to set
     */
    public void setVehiclePhoto(String vehiclePhoto) {
        this.vehiclePhoto = vehiclePhoto;
    }

    /**
     * @param status the status to set
     */
    public void setStatus(AuditStatus status) {
        this.status = status;
    }

    /**
     * @param declareTime the declareTime to set
     */
    public void setDeclareTime(Date declareTime) {
        this.declareTime = declareTime;
    }

    /**
     * @param declareStatus the declareStatus to set
     */
    public void setDeclareStatus(DeclareStatus declareStatus) {
        this.declareStatus = declareStatus;
    }

    /**
     * @param rejectReason the rejectReason to set
     */
    public void setRejectReason(String rejectReason) {
        this.rejectReason = rejectReason;
    }

    /**
     * @param vehicleStatus the vehicleStatus to set
     */
    public void setVehicleStatus(VehicleStatus vehicleStatus) {
        this.vehicleStatus = vehicleStatus;
    }

    /**
     * @param synchronize
     */
    public void setSynchronize(boolean synchronize) {
        this.synchronize = synchronize;
    }
    
    /**
     * @param bind the bind to set
     */
    public void setBind(boolean bind) {
        this.bind = bind;
    }

    /**
     * @param vam the vam to set
     */
    public void setVam(boolean vam) {
        this.vam = vam;
    }

    /**
     * @param vamId the vamId to set
     */
    public void setVamId(Long vamId) {
        this.vamId = vamId;
    }

    /**
     * @param creator the creator to set
     */
    public void setCreator(Long creator) {
        this.creator = creator;
    }

    /**
     * @param createTime the createTime to set
     */
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    /**
     * @param lastOperator the lastOperator to set
     */
    public void setLastOperator(Long lastOperator) {
        this.lastOperator = lastOperator;
    }

    /**
     * @param lastModifyTime the lastModifyTime to set
     */
    public void setLastModifyTime(Date lastModifyTime) {
        this.lastModifyTime = lastModifyTime;
    }

    /**
     * @param disabled the disabled to set
     */
    public void setDisabled(Boolean disabled) {
        this.disabled = disabled;
    }

}